package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.AmountUtil;
import com.huiminpay.common.cache.util.EncryptUtil;
import com.huiminpay.common.cache.util.IdWorkerUtils;
import com.huiminpay.common.cache.util.StringUtil;
import com.huiminpay.paymentagent.api.conf.AliConfigParam;
import com.huiminpay.paymentagent.api.dto.AlipayBean;
import com.huiminpay.paymentagent.api.service.IAlipaytAgentService;
import com.huiminpay.transaction.api.dto.*;
import com.huiminpay.transaction.api.service.IPlatformChannelService;
import com.huiminpay.transaction.api.service.ITransactionService;
import com.huiminpay.transaction.convert.PayOrderConvert;
import com.huiminpay.transaction.entity.PayOrder;
import com.huiminpay.transaction.mapper.PayOrderMapper;
import com.huiminpay.transaction.mq.MqConst;
import com.huiminpay.transaction.mq.PayProducter;
import com.yh.merchant.api.Service.IStoreService;
import com.yh.merchant.api.dto.StoreDTO;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.time.LocalDateTime;

/**
 * @ClassName : TransactionServiceImpl
 * @Author : 阿泽
 * @Date: 2021/8/11 21:41
 * @Description :
 */
@Service
public class  TransactionServiceImpl implements ITransactionService {

    @Reference
    IStoreService storeService;
    @Reference
    IAlipaytAgentService alipaytAgentService;
    @Reference
    IPlatformChannelService PlatformChannelService;
    @Autowired
    PayOrderMapper payOrderMapper;
    @Autowired
    PayProducter payProducter;
    @Value("${qr.entry}")
    private String qrEntry;
    @Override
    public String creatQrurl(QrcodeDto qrcodeDto) {
        //因为缺少门店信息 先查询
        StoreDTO  storeDTO  =storeService.selectById(qrcodeDto.getStoreId());
        qrcodeDto.setSubject(storeDTO.getStoreName()); //支付入口的标题
        qrcodeDto.setBody(storeDTO.getStoreName());

        PayOrderDTO payOrderDTO = new PayOrderDTO();
        BeanUtils.copyProperties(qrcodeDto,payOrderDTO);

        //拼接url
        String key = EncryptUtil.encodeUTF8StringBase64(JSON.toJSONString(payOrderDTO));
        String url = qrEntry+key;
        return url;
    }

    @Override
    public String createAlipayOrder(PayOrderDTO payOrderDTO) throws Exception {
        //0.订单号
        String tradeNo = IdWorkerUtils.getInstance().createUUID();

        String payChannel = "ALIPAY_WAP";
        String channel = "huimin_c2b";
        //1.下单 插入数据
        saveOrder(payOrderDTO, tradeNo, payChannel, channel);
        //2.调用支付宝代理服务

        //2.1业务参数
        String alipayWebHtml = doAlipayH5(payOrderDTO, tradeNo, payChannel, channel);

        //3.发送延迟消息
        PayOrderMqDTO payOrderMqDTO = new PayOrderMqDTO();
        payOrderMqDTO.setOutTradeNO(tradeNo);
        payOrderMqDTO.setPayChannell(payChannel);
        payProducter.sendMsgByDelay(MqConst.PAY_ORDER_LISTENER,payOrderMqDTO);
        return alipayWebHtml;
    }

    @Override
    public OrderResultDTO selectPayOrder(String outTradeNo) {
        QueryWrapper<PayOrder> qw = new QueryWrapper<>();
        qw.lambda().eq(PayOrder::getOutTradeNo,outTradeNo);
        PayOrder payOrder = payOrderMapper.selectOne(qw);

        return PayOrderConvert.INSTANCE.entity2dto(payOrder);
    }

    @Override
    public void updatePayOrderByTredeNo(OrderResultDTO orderResultDTO) {
        PayOrder payOrder = PayOrderConvert.INSTANCE.dto2entity(orderResultDTO);
        UpdateWrapper<PayOrder> qw = new UpdateWrapper<>();
        qw.lambda().eq(PayOrder::getOutTradeNo,orderResultDTO.getOutTradeNo());
        payOrderMapper.update(payOrder,qw);
    }

    /**
     * 调用支付宝手机网站支付
     * @param payOrderDTO
     * @param tradeNo
     * @param payChannel
     * @param channel
     * @return
     * @throws Exception
     */
    private String doAlipayH5(PayOrderDTO payOrderDTO, String tradeNo, String payChannel, String channel) throws Exception {
        //2.1业务参数
        AlipayBean alipayBean = new AlipayBean();
        alipayBean.setOutTradeNo(tradeNo);
        alipayBean.setBody(payOrderDTO.getBody());
        String ta = AmountUtil.changeF2Y(String.valueOf(payOrderDTO.getTotalAmount()));//分转元
        alipayBean.setTotalAmount(ta);
        alipayBean.setProductCode("QUICK_WAP_PAY");
        alipayBean.setSubject(payOrderDTO.getSubject());

        //2.2公共参数

        //String appId, String platformChannel, String payChannel
        PayChannelParamDTO paramDTO = PlatformChannelService.queryParamByAppPlatformAndPayChannel(payOrderDTO.getAppId(), channel, payChannel);
        String param = paramDTO.getParam();
        if (StringUtil.isEmpty(param)){
            throw new BusinessException(CommonErrorCode.UNKOWN);
        }
        AliConfigParam aliConfigParam1 = JSON.parseObject(param, AliConfigParam.class); //解析json获取公共参数

        alipayBean.setExpireTime("10m");//设置订单超时时间

        return alipaytAgentService.doAlipayWebApi(aliConfigParam1, alipayBean);
    }

    /**
     * 保存支付订单
     * @param payOrderDTO
     * @param tradeNo
     * @param payChannel
     * @param channel
     * @return
     */
    private PayOrder saveOrder(PayOrderDTO payOrderDTO, String tradeNo, String payChannel, String channel) {
        StoreDTO storeDTO = storeService.selectById(payOrderDTO.getStoreId());
        OrderResultDTO orderResultDTO = PayOrderConvert.INSTANCE.request2dto(payOrderDTO);
        orderResultDTO.setTradeNo(tradeNo);
        orderResultDTO.setMerchantId(storeDTO.getMerchantId());
        orderResultDTO.setPayChannel(payChannel);
        orderResultDTO.setChannel(channel);
        orderResultDTO.setOutTradeNo(tradeNo);
        orderResultDTO.setCurrency("CNY");
        /**
         * 交易状态支付状态,0-订单生成,1-支付中(目前未使用),2-支付成功,3-业务处理完成
         */
        orderResultDTO.setTradeState("0");
        orderResultDTO.setCreateTime(LocalDateTime.now());
        orderResultDTO.setUpdateTime(LocalDateTime.now());
        orderResultDTO.setExpireTime(LocalDateTime.now().plusMinutes(10L));
        orderResultDTO.setProductCode("QUICK_WAP_PAY");

        PayOrder payOrder = PayOrderConvert.INSTANCE.dto2entity(orderResultDTO);
        payOrderMapper.insert(payOrder);

        return payOrder;
    }
}
